﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Ue.Extensions
{
    public static class StringExtensions
    {
        /// <summary>
        ///  截取子字符串，每个中文字符和全角符号的长度为2。
        /// </summary>
        /// <param name="col"></param>
        /// <returns></returns>
        public static string SubstringByChineseRules(this string col, int length)
        {
            //if (string.IsNullOrEmpty(col))
            //    return string.Empty;

            //Regex cnRegex = new Regex("^[\u4e00-\u9fa5（）《》——；，。“”]$", RegexOptions.Compiled);

            //int tmplength = 0;
            //Char[] charArray = col.ToArray();
            //for (int i = 0; i < charArray.Length; i++)
            //{
            //    tmplength += cnRegex.IsMatch(charArray[i].ToString()) ? 2 : 1;
            //    if (tmplength == length)
            //    {
            //        return col.Substring(0, i + 1);
            //    }
            //    else if (tmplength > length)
            //    {
            //        return col.Substring(0, i);
            //    }
            //}

            //return col;
            return col.SubstringByChineseRules(0, length);
        }

        private static Encoding coding = Encoding.GetEncoding("gb2312");
        public static string SubstringByChineseRules(this string col, int startIndex, int length)
        {
            if (length < 0)
            {
                return string.Empty;
            }

            if (startIndex < 0)
            {
                startIndex = 0;
            }

            byte[] bytes = StringExtensions.coding.GetBytes(col);

            int caudaLength = bytes.Length - startIndex;
            if (caudaLength <= 0)
            {
                return string.Empty;
            }

            if (coding.GetString(bytes, 0, startIndex).EndsWith("?"))
            {
                startIndex += 1;
            }

            int subStringLength = caudaLength >= length
                ? length
                : caudaLength;

            return StringExtensions.coding.GetString(bytes, startIndex, subStringLength).TrimEnd('?');
        }

        /// <summary>
        /// 清除字符串中的空白区域
        /// </summary>
        /// <param name="col"></param>
        /// <returns></returns>
        public static string RemoveWhiteSpace(this string col)
        {
            bool changed = false;
            char[] output = col.ToCharArray();
            int cursor = 0;
            for (int i = 0, size = output.Length; i < size; i++)
            {
                char c = output[i];
                if (Char.IsWhiteSpace(c))
                {
                    changed = true;
                    continue;
                }

                output[cursor] = c;
                cursor++;
            }

            return changed ? new string(output, 0, cursor) : col;
        }

        /// <summary>
        /// 删除Html格式
        ///删除内容：html标签，script，<!---->注释，回车，换行，空格
        /// </summary>
        /// <param name="col"></param>
        /// <returns></returns>
        public static string RemoveHtml(this string col)
        {
            return Regex.Replace(col, @"<!--([\s\S])*?-->|<script([\s\S])*?/script>|<[^>]*>|&(nbsp|#160);|([\r\n])", "");
        }

        /// <summary>
        /// 根据分隔符切分字符串，并返回最后一个
        /// </summary>
        /// <returns></returns>
        public static string GetLastItemBy(this string col, char split)
        {
            string[] group = col.Split(split);

            return group[group.Length - 1];
        }

        /// <summary>
        /// 根据分隔符切分字符串，并返回第一个
        /// </summary>
        /// <returns></returns>
        public static string GetFirstItemBy(this string col, char split)
        {
            string[] group = col.Split(split);

            return group[0];
        }

        
        private readonly static Regex humps = new Regex("(?:^[a-zA-Z][^A-Z]*|[A-Z][^A-Z]*)");
        /// <summary>
        /// 将连续的书写的字符串（驼峰命名字格式），更改为友好的形式
        /// 如：“ACat”.CamelFriendly()=="A Cat"
        /// </summary>
        public static string CamelFriendly(this string camel)
        {
            if (String.IsNullOrWhiteSpace(camel))
                return "";

            var matches = humps.Matches(camel).OfType<Match>().Select(m => m.Value).ToArray();
            return matches.Any()
                ? matches.Aggregate((a, b) => a + " " + b).TrimStart(' ')
                : camel;
        }

        /// <summary>
        /// 将字符串转为16进制，用以解决中文乱码
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string ToHexString(this string col)
        {
            Func<char, bool> isNeedToEncode = chr =>
            {
                var reservedChars = "$-_.+!*'(),@=&";

                if (chr > 127)
                    return true;

                if (char.IsLetterOrDigit(chr) || reservedChars.IndexOf(chr) >= 0)
                    return false;

                return true;
            };

            Func<char, string> toHexString = chr =>
            {
                var encodedBytes = new UTF8Encoding().GetBytes(chr.ToString());
                var chrBuilder = new StringBuilder();
                foreach (var item in encodedBytes)
                {
                    chrBuilder.AppendFormat("%{0}", Convert.ToString(item, 16));
                }

                return chrBuilder.ToString();
            };

            var chars = col.ToCharArray();
            var builder = new StringBuilder();

            foreach (var chr in chars)
            {
                if (isNeedToEncode(chr))
                {
                    builder.Append(toHexString(chr));
                }
                else
                {
                    builder.Append(chr);
                }
            }

            return builder.ToString();
        }
    }
}
